我們今天來用DartPaf來練習
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Container(width: 100, height: 100, color: Colors.red)
    );
  }
}

我們能看Container
Container(
  color: Colors.red
),
Conainer的父級裝置屏幕,強制將Container變成和屏幕一樣大小
接著我們定義Container的大小
Container(width: 100, height: 100, color: Colors.red)

我們能看到Container想要變成100x100大小,但由於父widget強制約束他,使Container變成和屏幕相同大小
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Center(
			  child: Container(width: 100, height: 100, color: Colors.red),
			)
    );
  }
}

我們能看到螢幕強制Center與屏幕一樣大(嚴格約束),Center告訴Container可以變成任意大小,但不能超出屏幕(寬鬆約束)
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Center(
			  child: Container(width: double.infinity, height: 100, color: Colors.red),
			)
    );
  }
}
我們試著讓Container的width變成無限大Container(width: double.infinity, height: 100, color: Colors.red)
我們能看到,寬鬆布局約束讓Container不超過父widget
我們接著用UnconstrainedBox來創建無邊界約束
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: UnconstrainedBox(
        child: Container(color: Colors.red, width: 5000, height: 50),
      )
    );
  }
}
UnconstrainedBox允許子級的Container可以變為任意大小。
由於是任意大小,我們這邊讓Container的寬度為5000像素。這遠遠超出超出我們的屏幕,以至於無法容納,所以UnconstrainedBox將顯示溢出警告(overflow warning)
UnconstrainedBox(
	child: Container(color: Colors.red, width: 5000, height: 50),
)

接著我們把UnconstrainedBox加入一個父widget
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Center(
        child: UnconstrainedBox(
          child: Container(color: Colors.red, width: 5000, height: 50),
        )
      )
    );
  }
}
Center(
	child: UnconstrainedBox(
	  child: Container(color: Colors.red, width: 5000, height: 50),
	)
)
我們能看到出現溢出警告,但範圍不同
簡單的整理順序
1.裝置強制Center和裝置屏幕同樣大小,於是佔滿屏幕(嚴格布局約束)
2.Center允許UnconstrainedBox為不超過自己的任意大小(寬鬆布局約束)
3.UnconstrainedBox允許Container為任意大小(無邊界約束)
比較兩者溢出警告
Ex1的溢出警告是佔滿整個裝置屏幕,所以封鎖線是整個屏幕
Ex2的溢出警告則是超出我們Center,所以封鎖線是超出Center的範圍
接著我們使用OverflowBox
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: OverflowBox(
        minWidth: 0.0,
        minHeight: 0.0,
        maxWidth: double.infinity,
        maxHeight: double.infinity,
        child: Container(color: Colors.red, width: 5000, height: 50),
      )
    );
  }
}
OverflowBox(
	minWidth: 0.0,
	minHeight: 0.0,
	maxWidth: double.infinity,
	maxHeight: double.infinity,
	child: Container(color: Colors.red, width: 5000, height: 50),
)
屏幕強制OverflowBox變得和屏幕一樣大,然後OverflowBox允許其子widget設置為任意大小
OverflowBox與UnconstrainedBox類似,但不同的是,如果其子級超出該空間,它將不會顯示任何警告。
也就是在這種情況下,容器的寬度為5000像素,並且太大而無法容納在 OverflowBox 中,但是OverflowBox會全部顯示,而不會發出警告。

使用FittedBox
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const FittedBox(
        child: Text('Example Text Test !!'),
      )
    );
  }
}
const FittedBox(
	child: Text('Example Text Test !!'),
)
我們的FittedBox被強制和屏幕一樣大,並且Text則是有一個自然寬度(intrinsic width),它取決於文本數量,字體大小等因素。FittedBox讓Text可以變為任意大小。
但是在Text告訴FittedBox 其大小後,FittedBox 縮放text直到填滿所有可用寬度(被嚴格布局約束,強制FittedBox大小,導致Text被縮放)

接著我們在FittedBox的父widget使用Center
const Center(
  child: FittedBox(
    child: Text('Example Text Test !!'),
  ),
)
這裡Center將會讓FittedBox能夠變為不超過自己的任意大小。
FittedBox然後會根據Text調整自己的大小,然後讓 Text 可以變為所需的任意大小,由於二者俱有同一大小,因此不會發生縮放。(沒有被嚴格布局約束)

修改Text文本來測試單Text太大超出範圍會發生甚麼
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const Center(
        child: FittedBox(
          child: Text(
              'Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!'),
        ),
      )
    );
  }
}
我們知道FittedBox會嘗試根據Text大小調整大小,但不能大於widget的大小範圍。所以調整Text的大小以使其不超過屏幕
去掉FittedBox
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const Center(
          child: Text(
              'Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!'),
      )
    );
  }
}
能看到Text則會從屏幕上獲取其最大寬度,並在合適的地方換行
import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Row(
        children: [
          Container(
            color: Colors.red,
            child: const Text(
              'Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!',
            ),
          ),
          Container(color: Colors.blue, child: const Text('Hello Test!')),
        ],
      )
    );
  }
}
Row(
	children: [
	  Container(
		color: Colors.red,
		child: const Text(
		  'Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!',
		),
	  ),
	  Container(color: Colors.blue, child: const Text('Hello Test!')),
	],
)
Row不會對其子級施加任何約束(無邊界約束),因此它的children有可能超出Row的可用寬度。當超出時,Row會和UnconstrainedBox一樣顯示溢出警告(Column亦同)

Exapandedimport 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Row(
        children: [
          Expanded(
            child: Container(
              color: Colors.red,
              child: const Text(
                'Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!',
              ),
            ),
          ),
          Container(color: Colors.blue, child: const Text('Hello Test!')),
        ],
      )
    );
  }
}
也就是
Row(
	children: [
	  Expanded(
		child: Container(
		  color: Colors.red,
		  child: const Text(
			'Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!',
		  ),
		),
	  ),
	  Container(color: Colors.blue, child: const Text('Hello Test!')),
	],
)
當Row的子widget被包在了Expanded widget後,Row 會根據所有 Expanded 的子級來計算其該有的寬度。 使用Expanded,子widget自身的寬度就變得無關緊要,直接會被忽略掉

Flexibleimport 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Row(
        children: [
          Flexible(
            child: Container(
              color: Colors.red,
              child: const Text(
                'Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!Example Text Test !!',
              ),
            ),
          ),
          Container(color: Colors.blue, child: const Text('Hello Test!')),
        ],
      )
    );
  }
}
使用Flexible而不是Expanded的唯一的區別是
但無論是Expanded還是Flexible在它們決定子級大小時都會忽略其寬度。

今天簡單的介紹一些常見會出現的例子,我們明天見